package proxy;
 
import domain.MyTable;
import supper.BaseMapper;

import java.lang.reflect.*;
import java.util.Arrays;

//声明的增强方法 句柄
public class DefaultInvocation implements InvocationHandler {

	//将要被代理的目标对象
	private BaseMapper baseMapper;

	 public DefaultInvocation(BaseMapper baseMapper) {
		 this.baseMapper = baseMapper;
	 }
	 //invoke() 执行  参数1.proxy 当前被代理的对象 参数2:当前代理类被执行的方法 3.当前代理类的方法参数
	 public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
		System.out.println("被代理的类：" + baseMapper.getClass());
		 Type[] type = baseMapper.getClass().getGenericInterfaces();
		 ParameterizedType  parameter = (ParameterizedType) type[0];
		 Type[] typeArguments = parameter.getActualTypeArguments();
		 System.out.println("当前泛型是:"+typeArguments[0].getTypeName());
		 // com.itsource.domain.user
		 Class<?> aClass = Class.forName(typeArguments[0].getTypeName());
		 // 这个过程 spring帮你完成了属性注入,对象的前置后置处理,以及对象的销毁
		 Object o = aClass.newInstance();
		 System.out.println("拿到当前泛型的实例对象:"+o);
		 Arrays.asList(o.getClass().getDeclaredFields()).forEach(field -> {
			 field.setAccessible(true);
			 System.out.println("当前字段名称"+field.getName());
			 System.out.println("当前字段类型"+field.getType());
			 try {
				 System.out.println("当前字段值"+field.get(o));
			 } catch (IllegalAccessException e) {
				 throw new RuntimeException(e);
			 }
		 });
		 System.out.println("被代理的方法：" + method.getName());
		 //1.举例 如果当前是新增方法,此时我需要对这个方法做增强
		 if ("insert".equals(method.getName())){
			 MyTable myTable = (MyTable) o.getClass().getAnnotation(MyTable.class);
			 String tableName = myTable.name();
			 StringBuilder insert_into_ = new StringBuilder("insert into ")
					 .append(tableName)
					 .append("(");
			 Arrays.asList(o.getClass().getDeclaredFields()).forEach(field -> {
			 	//暴力获取private 修饰的字段
				 field.setAccessible(true);
				 insert_into_.append(field.getName()+",");
			 });
			 int i = insert_into_.lastIndexOf(",");
			 String substring = insert_into_.substring(0, i);
			 StringBuilder append = new StringBuilder(substring).append(")");
			 System.out.println(append);
			 append.append("values ( ");
			 Arrays.asList(o.getClass().getDeclaredFields()).forEach(field -> {
				 //暴力获取private 修饰的字段
				 field.setAccessible(true);
				 try {
					 append.append(field.get(o)+",");
				 } catch (IllegalAccessException e) {
					 e.printStackTrace();
				 }
			 });
			 String substring1 = append.substring(0, append.lastIndexOf(","));
			 StringBuilder append1 = new StringBuilder(substring1).append(")");
			 System.out.println(append1);
		 }
		System.out.println("被代理的接口方法的入参：" + args);
		Class<?> clazz = method.getDeclaringClass();

			// 还有method的入参个数、入参类型等等是否一直，此处忽略
			System.out.println("对方法做前置增强");
		 Object invoke = method.invoke(baseMapper, args);
		 System.out.println("对方法做后置增强");
			return invoke;
	}
}